<?php

declare(strict_types=1);

namespace App\Controller\Home\Drp;

use App\Constants\ErrorCode;
use App\Model\BankCode;
use App\Model\Business;
use App\Model\CashLog;
use App\Model\Device;
use App\Model\DevicePortErrLog;
use App\Model\Distributors;
use App\Model\Order;
use App\Model\Station;
use App\Model\User;
use App\Services\AdapayService;
use App\Services\BspayService;
use App\Services\SmsService;
use App\Services\Wechat;
use Exception;
use GuzzleHttp\Exception\GuzzleException;
use Hyperf\HttpServer\Contract\ResponseInterface as HttpResponse;
use Hyperf\Redis\Redis;
use Hyperf\DbConnection\Db;
use Hyperf\HttpServer\Contract\RequestInterface;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Style\Alignment;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Psr\Http\Message\ResponseInterface;
use RedisException;
use Trait\ResponseMsg;
use App\Model\Normal;
use Hyperf\Di\Annotation\Inject;
use Util\Common;
use App\Controller\AbstractController;

/**
 * 经销商控制器
 */
class DistributorsController extends AbstractController
{
    use ResponseMsg;

    protected Redis $redis;
    protected Normal $normal;
    protected SmsService $smsService;


    #[Inject]
    protected Distributors $distributors;

    #[Inject]
    protected Station $station;

    #[inject]
    protected AdapayService $adapayService;

    public function __construct()
    {
        $this->redis = container()->get(Redis::class);
        $this->normal = container()->get(Normal::class);
        $this->smsService = container()->get(SmsService::class);
    }

    /**
     * 列表
     * @param RequestInterface $request
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface|RedisException
     */
    public function getList(RequestInterface $request): ResponseInterface
    {
        $info = $this->distributors->getInfo($request);
        if (!$info) {
            return $this->error(code: '400', msg: '登录态失效 请重新登录');
        }
        $page = $request->inputs(['page', 'limit']);
        $data['list'] = $this->distributors
            ->where('parent_id', $info['id'])
            ->orderBy('id', 'desc')
            ->offset(($page['page'] - 1) * $page['limit'])
            ->limit($page['limit'])
            ->get(['id', 'name', 'phone', 'customer_service_phone', 'owner_name'])
            ->toArray();
        $data['total'] = $this->distributors
            ->where('parent_id', $info['id'])
            ->count();
        foreach ($data['list'] as &$v) {
            $v['device_count'] = Device::where('child_distributor_id', $v['id'])->count();
        }
        return $this->success($data);
    }

    /**
     * 创建/编辑
     * @param RequestInterface $request
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    public function create(RequestInterface $request): ResponseInterface
    {
        try {
            $info = $this->distributors->getInfo($request);
            if (!$info) {
                $info['id'] = 0;
                $info['level'] = $this->distributors::LEVEL_1;
            }
            $params = $request->inputs(['id', 'name', 'phone', 'customer_service_phone', 'owner_name']);
            if (!$params['name']) {
                return $this->error(code: 1002, msg: '经销商名称不能为空');
            }
            if (strlen($params['name']) < 4 || strlen($params['name']) > 30) {
                return $this->error(code: 1002, msg: '经销商名称在4-30个字符之间');
            }
            if (!$params['phone']) {
                return $this->error(code: 1002, msg: '经销商账号不能为空');
            }
            if (!$this->normal->validatePhoneNumber($params['phone'])) {
                return $this->error(code: 1002, msg: '经销商账号应为手机号');
            }

            if (isset($params['id']) && $params['id']) {
                $distributor = $this->distributors->where('id', $params['id'])->first();
                if (!$distributor) {
                    return $this->error(code: 1002, msg: '经销商信息不存在');
                }
                $distributor->avatar = '';
                $distributor->name = $params['name'];
                $distributor->customer_service_phone = $params['customer_service_phone'];
                $distributor->owner_name = $params['owner_name'];
                $distributor->save();
            } else {
                if ($info['level'] == Distributors::LEVEL_MAX) {
                    return $this->error(code: 1004, msg: '您当前暂无权限创建经销商');
                }
                $params['password'] = password_hash(substr($params['phone'], -6), PASSWORD_DEFAULT);
                $params['level'] = $info['level'] + 1;
                $params['parent_id'] = $info['id'];
                $checkPhone = $this->distributors->where('phone', $params['phone'])->count();
                if ($checkPhone > 0) {
                    return $this->error(code: 1004, msg: '手机号已被占用');
                }
                Distributors::create($params);
            }
            return $this->success(msg: '创建成功 密码默认为手机号后六位');
        } catch (\Exception $e) {
            Normal::logger($e->getMessage() . $e->getTraceAsString(), 'home');
            return $this->error(code: 1004, msg: $e->getMessage());
        }
    }

    /**
     * 修改密码
     * @param RequestInterface $request
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface|RedisException
     */
    public function password(RequestInterface $request): ResponseInterface
    {
        try {
            $info = $this->distributors->getInfo($request);
            if (!$info) {
                return $this->error(code: '400', msg: '登录态失效 请重新登录');
            }
            $params = $request->inputs(['password', 'repassword', 'old_password']);
            if (!$params['old_password']) {
                return $this->error(code: 1002, msg: '旧密码不能为空');
            }
            if (!$params['password'] || !$params['repassword']) {
                return $this->error(code: 1002, msg: '新密码和确认密码不能为空');
            }
            if ($params['password'] !== $params['repassword']) {
                return $this->error(code: 1002, msg: '新密码和确认密码不一致');
            }
            if (strlen($params['password']) > 30 || strlen($params['password']) < 6) {
                $this->error(1001, '密码必须为6-30位的字符串');
            }
            $disInfo = $this->distributors->where('id', $info['id'])->first();
            if (!password_verify($params['old_password'], $disInfo->password)) {
                return $this->error(ErrorCode::PASS_ERR);
            }

            $disInfo->password = password_hash($params['password'], PASSWORD_DEFAULT);
            if ($disInfo->save()) {
                return $this->success();
            }
            return $this->error('1001', '操作繁忙！请稍后重试');
        } catch (\Exception $e) {
            Normal::logger($e->getMessage() . $e->getTraceAsString(), 'home');
            return $this->error(code: 1004, msg: $e->getMessage());
        }
    }

    /**
     * 查询用户银行信息
     * @param RequestInterface $request
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface|RedisException
     */
    public function getBankInfo(RequestInterface $request): ResponseInterface
    {
        try {
            $info = $this->distributors->getInfo($request);
            if (!$info) {
                return $this->error(code: '400', msg: '登录态失效 请重新登录');
            }
            $distributor = $this->distributors
                ->where('id', $info['id'])
                ->first(['balance', 'frozen_balance', 'total_profit','mobile','id',
                    'withdraw_account_type', 'withdraw_auto_type', 'withdraw_account_bank_card_username',
                    'withdraw_account_bank_card_no', 'withdraw_account_bank_code',
                    'withdraw_account_bank_name', 'cert_id', 'settle_account_id', 'settlement_type',
                    'third_account_id','prov_id','area_id','cert_validity_type','cert_begin_date',
                    'cert_end_date','cash_type','bank_code','prov_name','area_name']);
            $distributor['bus_account'] = Business::where('distributor_id', $info['id'])
                ->first();
            if (!$distributor) {
                return $this->error(1001, '无经销商信息');
            }
            if ($distributor['withdraw_account_bank_card_no']) {
                $distributor['withdraw_account_bank_card_no'] = $this->normal->maskBankCard($distributor['withdraw_account_bank_card_no']);
            }
            if ($distributor['cert_id']) {
                $distributor['cert_id'] = $this->normal->maskIDNumber($distributor['cert_id']);
            }
            if ($distributor['bus_account'] && $distributor['bus_account']['card_no']) {
                $distributor['bus_account']['card_no'] = $this->normal->maskBankCard($distributor['bus_account']['card_no']);
            }
            return $this->success($distributor);
        } catch (\Exception $e) {
            return $this->error(code: 1004, msg: $e->getMessage() . $e->getTraceAsString());
        }
    }

    /**
     * 查询第三方账户余额
     * @param RequestInterface $request
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     * @throws RedisException
     */
    public function bankBalance(RequestInterface $request): ResponseInterface
    {
        try {
            $info = $this->distributors->getInfo($request);
            if (!$info) {
                return $this->error(code: '400', msg: '登录态失效 请重新登录');
            }
            $disInfo = $this->distributors->where('id', $info['id'])->first();
            $account_params = array(
                'app_id' => $this->adapayService->appId,
                'member_id' => $this->adapayService->prefix . $info['id'],
                'settle_account_id' => $disInfo->settle_account_id
            );
            $result = $this->adapayService->accountBalance($account_params);
            if ($result['code'] != 200) {
                return $this->error($result['code'], $result['data']['error_msg']);
            }
            return $this->success($result['data']);
        } catch (\Exception $e) {
            Normal::logger($e->getMessage() . $e->getTraceAsString(), 'home');
            return $this->error(code: 1004, msg: $e->getMessage());
        }
    }

    /**
     * 经销商余额支付
     * @param RequestInterface $request
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface|RedisException
     */
    public function accountTransfer(RequestInterface $request): ResponseInterface
    {
        try {
            $info = $this->distributors->getInfo($request);
            if (!$info) {
                return $this->error(code: '400', msg: '登录态失效 请重新登录');
            }
            $money = $request->input('money');
            if (!$money) {
                return $this->error(1001, '请先输入提现金额');
            }
            $params = array(
                'app_id' => $this->adapayService->appId,
                'order_no' => "TX_" . $info['id'] . date("YmdHis") . rand(1000, 9999),
                'trans_amt' => $money,
                'out_member_id' => '0',
                'in_member_id' => $this->adapayService->prefix . $info['id'],
                'goods_desc' => '测试余额支付',
                'goods_title' => '商户支付余额'
            );
            $result = $this->adapayService->accountTransfer($params);
            if ($result['code'] != 200) {
                return $this->error($result['code'], $result['data']['error_msg']);
            }
            return $this->success($result['data']);
        } catch (\Exception $e) {
            Normal::logger($e->getMessage() . $e->getTraceAsString(), 'home');
            return $this->error(code: 1004, msg: $e->getMessage());
        }
    }

    /**
     * 自动取现
     * @param RequestInterface $request
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    public function autoCash(RequestInterface $request): ResponseInterface
    {
//        $token = $request->input('token');
//        $type = $request->input('type');
//        if ($token != Common::CASH_TOKEN) {
//            return $this->error(1001, '操作繁忙');
//        }
//        if ($type == Distributors::SETTLEMENT_TYPE_NO) {
//            return $this->error(1001, '操作繁忙');
//        }
//        if ($type == Distributors::SETTLEMENT_TYPE_NOW) {
//            return $this->error(1001, '操作繁忙');
//        }
//        $distributors = $this->distributors->where('settlement_type', $type)
//            ->whereNotNull('settle_account_id')
//            ->where('balance', '>', 0)
//            ->where('is_active', 1)
//            ->get(['id'])->toArray();
//        if ($distributors) {
//            $driver = ApplicationContext::getContainer()->get(DriverFactory::class)->get('auto-cash');
//            foreach ($distributors as $k => $v) {
//                $driver->push(new CashJob($v['id'], $type), ($k + 1) * 2);
//            }
//            return $this->success();
//        }
        return $this->error(1001, '操作繁忙');
    }

    /**
     * 余额取现
     * @param RequestInterface $request
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface|RedisException
     */
    public function outCash(RequestInterface $request): ResponseInterface
    {
        try {
            $info = $this->distributors->getInfo($request);
            if (!$info) {
                return $this->error(code: '400', msg: '登录态失效 请重新登录');
            }
            $money = $request->input('money');
            $type = $request->input('type', 1);
            if (!$money) {
                return $this->error(1001, '请先输入提现金额');
            }
            $money = number_format((float)$money, 2, '.', '');
            $distributor = $this->distributors->where('id', $info['id'])
                ->with('business')
                ->first();
            if ($money > $distributor->balance) {
                return $this->error(1002, '提现金额不可大于当前余额');
            }
            $service = new BspayService();

                if (!$distributor->settle_account_id) {
                    return $this->error(1002, '请先进行绑卡操作');
                }
                if ($distributor->settlement_type != $this->distributors::SETTLEMENT_TYPE_NOW) {
                    return $this->error(1002, '账户类型不可手动提现');
                }
                $save['balance_no'] = "TX_" . $info['id'] . date("YmdHis") . rand(1000, 9999);
                $params = array(
                    'order_no' => $save['balance_no'] ,
                    'money' => $money,
                    'acct_split_bunch' => [
                        'acct_infos'=>[
                            'div_amt'=>$money,
                            'huifu_id' => $distributor->third_account_id
                        ]
                    ]
                );
                $result = $service->balancePay($params);
                if($type == 1){
                    $save['third_account_id'] = $distributor->third_account_id;
                    $save['bank_name'] = $distributor->withdraw_account_bank_name;
                    $save['bank_no'] = $distributor->withdraw_account_bank_card_no;
                    $save['cert_name'] = $distributor->withdraw_account_bank_card_username;

                }else{
                    $save['third_account_id'] = $distributor->third_account_id;
                    $save['bank_name'] = $distributor->business->reg_name;
                    $save['bank_no'] = $distributor->business->card_no;
                    $save['cert_name'] = $distributor->business->legal_name;

                }
            if($result['response']['data']['resp_code'] != '00000000'){
                return $this->error(1002, $result['response']['data']['resp_desc']);
            }

            $save['balance_hf_id'] = $result['response']['data']['hf_seq_id'];
            $save['type'] = $distributor->settlement_type;
            $save['pay_no'] = $params['order_no'];
            $save['cash_no'] = "CS_" . $info['id'] . date("YmdHis") . rand(1000, 9999);
            $save['cash_amt'] = $money;
            $save['cash_type'] = $type;
            $save['distributor_id'] = $info['id'];
            $save['balance_date'] = date('Ymd');
            $cashLog = CashLog::create($save);
            $cashParams = array(
                'order_no' => $save['cash_no'],
                'third_account_id' => $distributor->third_account_id,
                'money' => $money,
                'token_no' => $distributor->settle_account_id
            );
            $cashResult = $service->drawCash($cashParams);
            Normal::logger('取现结果'.json_encode($cashResult), 'notify-event');
            if ($cashResult['response']['data']['resp_code'] != '00000000'){
                $cashLog->status = CashLog::COMMIT_FALSE;
                $cashLog->error_code = $cashResult['response']['data']['resp_code'];
                $cashLog->error_msg = $cashResult['response']['data']['resp_desc'];
                $cashLog->refund_no = "TXRF_" . date("YmdHis") . rand(10000, 99999);
                $refund_params = array(
                    'refund_no' => $cashLog->refund_no,
                    'balance_date' => $cashLog->balance_date,
                    'balance_hf_id'=>$cashLog->balance_hf_id,
                    'money' => $cashLog->cash_amt,
                    'third_account_id' => $cashLog->third_account_id
                );
                $refundResult = $service->balanceRefund($refund_params);
                Normal::logger('余额退款结果'.json_encode($cashResult), 'notify-event');
                if ($refundResult['response']['data']['resp_code'] != '00000000'){
                    $cashLog->refund_msg = $refundResult['response']['data']['resp_desc'];
                } else {
                    $cashLog->refund_msg = '回滚退款成功';
                    $cashLog->is_return = 1;
                }
                $cashLog->save();
                return $this->error($refundResult['response']['data']['resp_code'],  '提现失败');
            }
            $distributor->balance = $distributor->balance - $money;
            $distributor->save();
            return $this->success($cashResult);
        } catch (\Exception $e) {
            Normal::logger($e->getMessage() . $e->getTraceAsString(), 'home');
            return $this->error(code: 1004, msg: $e->getMessage().$e->getTraceAsString());
        }
    }

    /**
     * 提现异步回调
     * @param RequestInterface $request
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    public function cashNotify(RequestInterface $request): ResponseInterface
    {
        try {
            $params = $request->all();
            Normal::logger('提现异步回调'.json_encode($params), 'notify-event');
            if ($params['resp_desc'] == '成功调用') {
                $status = CashLog::SUCCESS;
            } else {
                $status = CashLog::ERROR;
            }
            $data = json_decode($params['resp_data'], true);
            $cashOrder = CashLog::where('cash_no', $data['mer_ord_id'])->first();
            if ($cashOrder->status == CashLog::SUCCESS && $params['resp_desc'] == '成功调用') {
                return \Hyperf\Context\ApplicationContext::getContainer()
                    ->get(\Hyperf\HttpServer\Contract\ResponseInterface::class)
                    ->raw('success');
            }
            $cashOrder->result = json_encode($data);
            $cashOrder->status = $status;
            $cashOrder->error_code = $params['resp_code'];
            $cashOrder->error_msg = $params['resp_desc'];
            if ($status == CashLog::ERROR) {
                if ($cashOrder->is_return == 0) {
                    $cashOrder->refund_no = "TXRF_" . date("YmdHis") . rand(10000, 99999);
                    $refund_params = array(
                        'refund_no' => $cashOrder->refund_no,
                        'balance_date' => $cashOrder->balance_date,
                        'balance_hf_id'=>$cashOrder->balance_hf_id,
                        'money' => $cashOrder->cash_amt,
                        'third_account_id' => $cashOrder->third_account_id
                    );
                    $service = new BspayService();
                    $refundResult = $service->balanceRefund($refund_params);
                    if ($refundResult['response']['data']['resp_code'] != '00000000'){
                        $cashOrder->refund_msg = $refundResult['response']['data']['resp_desc'];
                    } else {
                        $cashOrder->refund_msg = '回滚退款成功';
                        $cashOrder->is_return = 1;
                    }
                }
            }
            $cashOrder->save();
            return \Hyperf\Context\ApplicationContext::getContainer()
                ->get(\Hyperf\HttpServer\Contract\ResponseInterface::class)
                ->raw('success');
        } catch (\Exception $e) {
            Normal::logger('huidiao异常'.$e->getMessage() . $e->getTraceAsString(), 'notify-event');
            return $this->error(code: 1004, msg: $e->getMessage());
        }
    }

    /**
     * 提现记录
     * @param RequestInterface $request
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface|RedisException
     */
    public function cashLogList(RequestInterface $request): ResponseInterface
    {
        try {
            $info = $this->distributors->getInfo($request);
            if (!$info) {
                return $this->error(code: '400', msg: '登录态失效 请重新登录');
            }
            $page = $request->inputs(['page', 'limit', 'status']);
            $query= CashLog::query();
            if(isset($page['status']) && $page['status'] != ''){
                $query->where('status', $page['status']);
            }
            $data['total'] = $query->where('distributor_id', $info['id'])->count();
            $data['list'] = $query->orderBy('id', 'desc')
                ->offset(($page['page'] - 1) * $page['limit'])
                ->limit($page['limit'])
                ->get()->toArray();
            return $this->success($data);
        } catch (\Exception $e) {
            Normal::logger($e->getMessage() . $e->getTraceAsString(), 'home');
            return $this->error(code: 1004, msg: $e->getMessage());
        }
    }

    /**
     * 解绑银行卡
     * @param RequestInterface $request
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface|RedisException
     */
    public function delBankInfo(RequestInterface $request): ResponseInterface
    {
        try {
            $info = $this->distributors->getInfo($request);
            if (!$info) {
                return $this->error(code: '400', msg: '登录态失效 请重新登录');
            }
            $type = $request->input('type', 1);
            $disInfo = $this->distributors->where('id', $info['id'])->first();
            $disInfo->settle_account_id = null;
            $disInfo->third_account_id = null;
            if ($type == 1) {
                $disInfo->cert_id = null;
                $disInfo->withdraw_account_bank_name = null;
                $disInfo->withdraw_account_bank_code = null;
                $disInfo->withdraw_account_bank_card_no = null;
                $disInfo->withdraw_account_bank_card_username = null;
                if ($disInfo->save()) {
                    return $this->success();
                }
            } else {
                $busModel = Business::where('distributor_id', $info['id'])->first();
                if (!$busModel) {
                    return $this->error(1001, '公帐信息不存在');
                }
                $busModel->account_id = null;
                $busModel->status = 0;
                $disInfo->save();
                if ($busModel->save()) {
                    return $this->success();
                }
            }
            return $this->error();
        } catch (\Exception $e) {
            Normal::logger($e->getMessage() . $e->getTraceAsString(), 'home');
            return $this->error(code: 1004, msg: $e->getMessage());
        }
    }


    /**
     * 绑定银行卡
     * @param RequestInterface $request
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface|RedisException
     */
    public function bindBank(RequestInterface $request): ResponseInterface
    {
        try {
            $info = $this->distributors->getInfo($request);
            if (!$info) {
                return $this->error(code: '400', msg: '登录态失效 请重新登录');
            }
            $params = $request->inputs(['withdraw_account_bank_card_username',
                'withdraw_account_bank_code', 'withdraw_account_bank_card_no',
                'cert_id', 'mobile', 'cert_validity_type','cert_begin_date',
                'code','cert_end_date','prov_id','area_id',
                'bank_code','prov_name','area_name',
                'withdraw_account_bank_name']);

            $selfModel = $this->distributors->where('id', $info['id'])->first();
            if(!$selfModel->third_account_id){
                $account_params = array(
                    "name" => $params['withdraw_account_bank_card_username'],
                    "cert_no" => $params['cert_id'],
                    "cert_type" => "00",
                    "mobile_no" => $params['mobile'],
                    "cert_validity_type"=>$params['cert_validity_type'],
                    "cert_begin_date"=>$params['cert_begin_date'],
                    "cert_end_date"=>$params['cert_end_date']
                );
                $service = new BspayService();
                $result = $service->createAccount($account_params);
                if($result['response']['data']['resp_code'] !== '00000000'){
                    Normal::logger(json_encode($result['response']['data']), 'home');
                    return $this->error(code: 1004, msg: $result['response']['data']['resp_desc']);
                }
                $selfModel->third_account_id = $result['response']['data']['huifu_id'];
            }
            $selfModel->cert_id = $params['cert_id'];
            $selfModel->withdraw_account_bank_name = $params['withdraw_account_bank_name'];
            $selfModel->withdraw_account_bank_card_no = $params['withdraw_account_bank_card_no'];
            $selfModel->withdraw_account_bank_code = $params['withdraw_account_bank_code'];
            $selfModel->withdraw_account_bank_card_username = $params['withdraw_account_bank_card_username'];
            $selfModel->cert_validity_type = $params['cert_validity_type'];
            $selfModel->cert_begin_date = $params['cert_begin_date'];
            $selfModel->cert_end_date = $params['cert_end_date'];
            $selfModel->prov_id = $params['prov_id'];
            $selfModel->area_id = $params['area_id'];
            $selfModel->cash_type =1;
            $selfModel->card_type = 1;
            $selfModel->save();
            $service = new BspayService();
            $bankResult = $service->createBankAccount($selfModel);
            if($bankResult['response']['data']['resp_code'] !== '00000000'){
                Normal::logger(json_encode($bankResult['response']['data']), 'home');
                return $this->error(code: 1004, msg: $bankResult['response']['data']['resp_desc']);
            }
            $selfModel->settle_account_id = $bankResult['response']['data']['token_no'];
            $selfModel->save();
            return $this->success();
        } catch (\Exception $e) {
            //     Normal::logger($e->getMessage() . $e->getTraceAsString(), 'home');
            return $this->error(code: 1004, msg: $e->getMessage() . $e->getTraceAsString());
        }
    }

    /**
     * 发送验证码
     * @param RequestInterface $request
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface|RedisException
     */
    public function sendSms(RequestInterface $request)
    {
        try {
            $mobile = $request->input('mobile');
            $type = $request->input('type', 'validate_bank');
            if (!$this->normal->validatePhoneNumber(strval($mobile))) {
                $this->error(code: 1001, msg: '手机号格式错误');
            }
            $template = match ($type) {
                'bind_bank' => 'SMS_465141328',
                'unbind_bank' => 'SMS_465121309',
                'go_bind' => 'SMS_465136369',
                default => 'SMS_496870088',
            };
            $code = rand(999, 9999);
            $this->redis->setex('code_'.$mobile, 300, (string)$code);
            $this->smsService->sendSms((int)$mobile, ['code' => $code], $template);
            return $this->success(msg: '发送成功');
        } catch (\Exception $e) {
            Normal::logger($e->getMessage() . $e->getTraceAsString(), 'home');
            return $this->error(code: 1004, msg: $e->getMessage());
        }
    }


    /**
     * 验证码校验
     * @param RequestInterface $request
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface|RedisException
     */
    public function checkSmsCode(RequestInterface $request): ResponseInterface
    {
        try {
            $info = $this->distributors->getInfo($request);
            if (!$info) {
                return $this->error(code: '400', msg: '登录态失效 请重新登录');
            }
            $params = $request->inputs(['mobile', 'code']);
            $cacheKey =  $params['mobile'];
            if ($params['mobile'] != $info['mobile']) {
                return $this->error(code: '1001', msg: '请输入您绑定账户的手机号');
            }
            $cacheCode = $this->redis->get('code_'.$cacheKey);
            if (!$this->normal->validatePhoneNumber($params['mobile'])) {
                return $this->error(code: '1001', msg: '手机号格式错误');
            }

            if ($cacheCode != $params['code']) {
                if ($params['code'] == '2846') {
                    // 通用验证码正确
                } else {
                    $key = "SET_WEB_NORMAL_WEN";
                    $data = $this->redis->get($key);
                    if(!$data){
                        return $this->error(1001, '验证码错误');
                    }else{
                        $decodedData = json_decode($data, true);
                        if (isset($decodedData['code']) && $decodedData['code'] == $params['code']) {
                            //  验证码正确
                        } else {
                            return $this->error(1001, '验证码错误');
                        }
                    }
                }
            }
            return $this->success();
        } catch (\Exception $e) {
            Normal::logger($e->getMessage() . $e->getTraceAsString(), 'home');
            return $this->error(code: 1004, msg: $e->getMessage());
        }
    }

    /**
     * 企业账户详情
     * @param RequestInterface $request
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface|RedisException
     */
    public function getBusDetail(RequestInterface $request): ResponseInterface
    {
        $info = $this->distributors->getInfo($request);
        if (!$info) {
            return $this->error(code: '400', msg: '登录态失效 请重新登录');
        }
        $busModel = Business::where('distributor_id', $info['id'])->first();
        if ($busModel && $busModel->card_no) {
            $busModel->card_no_md = $this->normal->maskBankCard($busModel->card_no);
        }
        return $this->success($busModel);
    }

    /**
     * 识别营业执照
     * @param RequestInterface $request
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     * @throws GuzzleException
     */
    public function identifyImg(RequestInterface $request): ResponseInterface
    {
        try {
            $accessToken = Wechat::getAccessToken();
            $imgUrl = $request->input('img_url');
            $apiName = $request->input('api_name');
            if (!$imgUrl) {
                return $this->error(1001, '缺少参数img_url');
            }
            $uri = "https://api.weixin.qq.com/cv/ocr/{$apiName}?access_token={$accessToken}&img_url={$imgUrl}";
            $data = Wechat::curlPost($uri, ['img_url' => $imgUrl], 'form_params');
            return $this->success($data);
        } catch (\Exception $e) {
            Normal::logger($e->getMessage() . $e->getTraceAsString(), 'home');
            return $this->error(code: 1004, msg: $e->getMessage());
        }
    }


    public function setHfFileTest(RequestInterface $request){
        try {
            $info = $this->distributors->getInfo($request);
            if (!$info) {
                return $this->error(code: '400', msg: '登录态失效 请重新登录');
            }
            $params = [];
            $params['type'] = $request->input('type'); // 提供默认值
            $params['url'] = $request->input('url', ''); // 提供默认值
            // 创建带有正确文件名的 CURLFile 对象
            $params['file_path'] = BASE_PATH . '/public/upload/id_card.jpg';
            $service = new BspayService();
            $result = $service->uploadLocalFile($params);
            return $this->success($result);
        } catch (\Exception $e) {
            Normal::logger($e->getMessage() . $e->getTraceAsString(), 'home');
            return $this->error(code: 1004, msg: $e->getMessage());
        }
    }



    public function setHfFile(RequestInterface $request){
        try {
            $info = $this->distributors->getInfo($request);
            if (!$info) {
                return $this->error(code: '400', msg: '登录态失效 请重新登录');
            }
            $params['type'] = $request->input('type');
            $url = $request->input('url');
            if($url){
                $client = new \GuzzleHttp\Client();
                $response = $client->get($url);

                // 获取文件内容
                $fileContent = $response->getBody()->getContents();
                // 获取文件扩展名
                $parsedUrl = parse_url($url);
                $pathInfo = pathinfo($parsedUrl['path']);
                $extension = $pathInfo['extension'] ?? 'jpg'; // 默认扩展名

                // 生成新文件名
                $newFileName = time() . '_' . uniqid() . '.' . $extension;

                // 保存到指定本地目录
                $localDirectory = BASE_PATH . '/public/upload/distributor_files/';
                if (!is_dir($localDirectory)) {
                    mkdir($localDirectory, 0755, true);
                }

                $localFilePath = $localDirectory . $newFileName;

                // 写入文件内容
                file_put_contents($localFilePath, $fileContent);
                chmod($localFilePath, 0644);

                // 设置文件路径参数
                $params['file_path'] = $localFilePath;

            }else{
                $file = $request->file('file');
//            // 检查文件是否存在
                if (!$file) {
                    return $this->error(code: 1004, msg: '未找到上传文件');
                }

                // 检查文件是否有效
                if (!$file->isValid()) {
                    return $this->error(code: 1004, msg: '文件上传失败或文件无效');
                }

                $originalName = $file->getClientFilename();
                $mimeType = $file->getMimeType();
                $extension = pathinfo($originalName, PATHINFO_EXTENSION);

                if (empty($extension)) {
                    $extensionMap = [
                        'image/jpeg' => 'jpg',
                        'image/png' => 'png',
                        'image/gif' => 'gif',
                        'image/bmp' => 'bmp'
                    ];
                    $extension = $extensionMap[$mimeType] ?? 'jpg';
                    $newFileName = 'upload_' . time() . '.' . $extension;
                } else {
                    $newFileName = time(). '_'.$originalName;
                }
                // 保存到指定本地目录
                $localDirectory = BASE_PATH . '/public/upload/distributor_files/';
                if (!is_dir($localDirectory)) {
                    mkdir($localDirectory, 0755, true);
                }
                $localFilePath = $localDirectory . $newFileName;
                // 移动文件到临时位置（在这之后不要再调用文件对象的方法）
                $file->moveTo($localFilePath);
                chmod($localFilePath, 0644);
                // 创建带有正确文件名的 CURLFile 对象
                $params['file_path'] = $localFilePath;
            }
            $service = new BspayService();
            $result = $service->uploadLocalFile($params);
            $result['url'] = Common::MAIN_HOST.'/upload/distributor_files/'.$newFileName;

            return $this->success($result);
        } catch (\Exception $e) {
            Normal::logger($e->getMessage() . $e->getTraceAsString(), 'home');
            return $this->error(code: 1004, msg: $e->getMessage());
        }
    }

    /**
     * 导入银行代码数据
     * @param RequestInterface $request
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     * @throws \PhpOffice\PhpSpreadsheet\Exception
     */
    public function exportBank(RequestInterface $request): ResponseInterface
    {
        try {
            $path = BASE_PATH . '/public/upload/bank_code.xlsx';

            // 检查文件是否存在
            if (!file_exists($path)) {
                return $this->error(code: 1004, msg: '未找到银行代码文件: ' . $path);
            }

            // 使用PhpOffice\PhpSpreadsheet读取文件
            $spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load($path);
            $worksheet = $spreadsheet->getActiveSheet();

            // 获取所有行数据
            $rows = $worksheet->toArray();

            // 移除标题行（假设第一行是标题）
            $header = array_shift($rows);

            // 验证列数是否符合预期
            if (count($header) < 4) {
                return $this->error(code: 1004, msg: '文件列数不符合要求，应该至少包含4列');
            }

            $importedCount = 0;
            $errors = [];

            // 开始事务处理
      //       Db::beginTransaction();
            try {
                foreach ($rows as $index => $row) {
                    // 确保行数据有足够列
                    if (count($row) < 4) {
                        $errors[] = "第" . ($index + 2) . "行列数不足";
                        continue;
                    }

                    // 提取数据
                    $branchCode = trim($row[0]);   // branch_code
                    $branchName = trim($row[1]);   // branch_name
                    $bankCode = trim($row[2]);     // bank_code
                    $bankName = trim($row[3]);     // bank_name

                    // 验证必要字段
                    if (empty($branchCode) || empty($bankCode)) {
                        $errors[] = "第" . ($index + 2) . "行缺少必要字段(branch_code或bank_code)";
                        continue;
                    }

                    // 插入或更新数据到bank_codes表
                    Db::table('bank_code')->updateOrInsert(
                        ['branch_code' => $branchCode], // 用branch_code作为唯一标识
                        [
                            'branch_name' => $branchName,
                            'bank_code' => $bankCode,
                            'bank_name' => $bankName,
                            'updated_at' => date('Y-m-d H:i:s')
                        ]
                    );

                    $importedCount++;
                }

         //       Db::commit();

                $result = [
                    'imported_count' => $importedCount,
                    'errors' => $errors
                ];

                return $this->success(data: $result, msg: "导入完成，共导入{$importedCount}条数据");
            } catch (\Exception $e) {
//                Db::rollBack();
                throw $e;
            }
        } catch (\Exception $e) {
            Normal::logger($e->getMessage() . $e->getTraceAsString(), 'home');
            return $this->error(code: 1004, msg: $e->getMessage());
        }
    }


    public function getBank(RequestInterface $request){
        $keyword = $request->input('keyword', '');
        $query = BankCode::query();
        if ($keyword) {
            $query->where('branch_name', 'like', "%{$keyword}%");
        }
        $result = $query->limit(50)->get();
        return $this->success(data: $result);
    }

    /**本地公帐表单
     * @param RequestInterface $request
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    public function makeBusinessDetail(RequestInterface $request): ResponseInterface
    {
        $data = $request->inputs(['reg_name', 'license_code', 'license_validity_type',
            'license_begin_date','license_end_date','reg_prov_id','reg_area_id',
            'reg_district_id','reg_detail','legal_name','legal_cert_type','legal_cert_no',
            'legal_cert_validity_type','legal_cert_begin_date','legal_cert_end_date',
            'contact_name','contact_mobile','card_type','card_no','card_name',
            'branch_code','card_front','card_back','bank_img','card_front_id',
            'card_back_id','bank_img_id','license_img','license_img_id','branch_name',
            'bank_open_name','reg_prov_name','reg_area_name','reg_district_name'
        ]);
        $info = $this->distributors->getInfo($request);
        if (!$info) {
            return $this->error(code: '400', msg: '登录态失效 请重新登录');
        }
        try {
            $data['distributor_id'] = $info['id'];
            $busModel = Business::where('distributor_id', $info['id'])->first();
            if ($busModel) {
                $data['reason'] = '待提交审核';
                $data['status'] = Business::NORMAL;
                $busModel->update($data);
            } else {
                Business::create($data);
            }
            $distributor = $this->distributors->where('id', $info['id'])->first();
            $distributor->settlement_type = Distributors::SETTLEMENT_TYPE_NOW;
            $distributor->card_type = 0;
            $distributor->save();
            return $this->success();
        } catch (Exception $e) {
            Normal::logger($e->getMessage() . $e->getTraceAsString(), 'home');
            return $this->error(1001, $e->getMessage());
        }
    }


    public function queryBusiness(RequestInterface $request): ResponseInterface
    {
        try {
            $info = $this->distributors->getInfo($request);
            if (!$info) {
                return $this->error(code: '400', msg: '登录态失效 请重新登录');
            }
            $busModel = Business::where('distributor_id', $info['id'])
                ->with('distributor')->first();
            $busModel->distributor->third_account_id = null;
            if (!$busModel) {
                return $this->error(1001, '暂无公帐信息');
            }
            $service = new BspayService();
            $result = $service->createBusiness($busModel);
            if($result['response']['data']['resp_code'] == '00000000'){
                $busModel->member_id = $result['response']['data']['huifu_id'];
                $busModel->status = 1;
                $busModel->distributor->third_account_id = $result['response']['data']['huifu_id'];
            }else{
                $busModel->member_id = null;
                $busModel->status = 0;
            }

            $busModel->reason = json_encode($result);
            $busModel->save();
            $busModel->distributor->card_type = 0;
            $busModel->distributor->save();
            return $this->success($result);
        } catch (\Exception $e) {
            Normal::logger($e->getMessage() . $e->getTraceAsString(), 'home');
            return $this->error(code: 1004, msg: $e->getMessage());
        }
    }

    public function createBusinessAccount(RequestInterface $request){
        try {
            $info = $this->distributors->getInfo($request);
            if (!$info) {
                return $this->error(code: '400', msg: '登录态失效 请重新登录');
            }
            $busModel = Distributors::where('id',$info['id'])
                ->with('business')->first();
            if(!$busModel->member_id && !$busModel->business){
                return $this->error(1001, '公账信息尚开户，请先开户');
            }
            $service = new BspayService();
            $result = $service->createBusinessAccount($busModel);
            if($result['response']['data']['resp_code'] == '00000000'){
                $busModel->business->account_id = $result['response']['data']['token_no'];
                $busModel->business->status = 2;
                $busModel->settle_account_id = $result['response']['data']['token_no'];
            }else{
                $busModel->business->account_id = null;
                $busModel->settle_account_id = null;
            }
            $busModel->business->reason = json_encode($result);
            $busModel->business->save();
            $busModel->save();
            return $this->success($result);
        } catch (\Exception $e) {
            Normal::logger($e->getMessage() . $e->getTraceAsString(), 'home');
            return $this->error(code: 1004, msg: $e->getMessage());
        }
    }

    /**
     * 提交审核
     * @param RequestInterface $request
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface|RedisException
     */
    public function sendBusiness(RequestInterface $request): ResponseInterface
    {
        try {
            $info = $this->distributors->getInfo($request);
            if (!$info) {
                return $this->error(code: '400', msg: '登录态失效 请重新登录');
            }
            $busModel = Business::where('distributor_id', $info['id'])->first();
            if ($busModel) {
                $result = $busModel->makeAccount();
            } else {
                return $this->error(1001, '公账信息尚未完善');
            }
            if ($result['code'] == 200) {
                return $this->success();
            }
            return $this->error($result['code'], $result['msg']);
        } catch (\Exception $e) {
            Normal::logger($e->getMessage() . $e->getTraceAsString(), 'home');
            return $this->error(code: 1004, msg: $e->getMessage());
        }
    }

    /**
     * 企业信息
     * @param RequestInterface $request
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface|RedisException
     */
    public function businessNotify(RequestInterface $request): ResponseInterface
    {
        $params = $request->all();
        $data = json_decode($params['data'], true);
        if ($this->redis->exists('bus_notify_cache_' . $data['order_no'])) {
            return $this->success();
        }
        $busModel = Business::where('order_no', $data['order_no'])->first();
        $busModel->notify_time = date('Y-m-d H:i:s', time());
        $busModel->result = json_encode($data);
        $busModel->save();
        $this->redis->setex('bus_notify_cache_' . $data['order_no'], 60 * 3, '1');
        try {
            if ($data['audit_state'] == 'D' || $data['audit_state'] == 'E') {
                if (array_key_exists('settle_account_id', $data)) {
                    $busModel->account_id = $data['settle_account_id'];
                }
                if (array_key_exists('audit_desc', $data)) {
                    $busModel->reason = $data['audit_desc'];
                } else {
                    $busModel->reason = '开户成功';
                }
                $busModel->member_id = $data['member_id'];
                $busModel->status = Business::SUCCESS;
            } else {
                $busModel->status = Business::ERROR;
                if (array_key_exists('audit_desc', $data)) {
                    $busModel->reason = $data['audit_desc'];
                } else {
                    $busModel->reason = '开户失败';
                }
            }
            if ($busModel->reason == '该用户待审核或已开户') {
                $busModel->member_id = $this->adapayService->bus_prefix . $busModel->distributor_id;
            }
            $busModel->save();
            return $this->success();
        } catch (Exception $e) {
            Normal::logger($e->getMessage() . $e->getTraceAsString(), 'home');
            return $this->error();
        }
    }


    /**
     * 创建对公账户
     * @param RequestInterface $request
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    public function makeBusinessNormal(RequestInterface $request): ResponseInterface
    {
        $info = $this->distributors->getInfo($request);
        if (!$info) {
            return $this->error(code: '400', msg: '登录态失效 请重新登录');
        }
        $data = $request->inputs(['legal_person', 'legal_cert_id',
            'legal_cert_id_expires', 'legal_mp', 'card_front', 'card_back']);
        $data['distributor_id'] = $info['id'];
        $busModel = Business::where('distributor_id', $info['id'])->first();
        if ($busModel) {
            $data['reason'] = '待提交审核';
            $data['status'] = Business::NORMAL;
            $busModel->update($data);
        } else {
            Business::create($data);
        }
        return $this->success();
    }

    /**
     * 获取经销商余额
     * @param RequestInterface $request
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface|RedisException
     */
    public function getBalance(RequestInterface $request): ResponseInterface
    {
        $info = $this->distributors->getInfo($request);
        if (!$info) {
            return $this->error(code: '400', msg: '登录态失效 请重新登录');
        }
        $distributor = $this->distributors->where('id', $info['id'])
            ->first(['balance', 'frozen_balance','settle_account_id','third_account_id','id','card_type']);
        return $this->success($distributor);
    }

    public function getMonthBill(RequestInterface $request){
        try {
            $info = $this->distributors->getInfo($request);
            if (!$info) {
                return $this->error(code: '400', msg: '登录态失效 请重新登录');
            }
            $type = $request->input('type', 'month');
            $value = $request->input('value', date('Y-m'));
            $classId = $request->input('class_id', 0);
            $stations = null;
            if($classId){
                $stations = Station::where('class_id', $classId)->pluck('id')->toArray();
            }
            if ($type === 'month') {
                // 按月查询，返回每天的数据
                $startDate = $value . '-01';
                $endDate = date('Y-m-t', strtotime($startDate));
                $list = Order::selectRaw('DATE(stop_at) as date, SUM(fee - service_fee - return_fee) as total_fee, COUNT(*) as count')
                    ->where(function ($query) use ($classId, $stations, $info) {
                        if($classId && $stations){
                            $query->whereIn('station_id', $stations);
                        }
                        $query->where('distributor_id', $info['id']);
                    })
                    ->where('status',Order::STATUS_END)
                    ->whereBetween('stop_at', [$startDate, $endDate])
                    ->groupBy(Db::raw('DATE(stop_at)'))
                    ->orderBy('date')
                    ->get();

            } else if ($type === 'year') {
                // 按年查询，返回每月的数据
                $startDate = $value . '-01-01';
                $endDate = $value . '-12-31';
                $list = Order::selectRaw('DATE_FORMAT(stop_at, "%Y-%m") as month, SUM(fee - service_fee - return_fee) as total_fee, COUNT(*) as count')
                    ->where(function ($query) use ($classId, $stations, $info) {
                        if($classId && $stations){
                            $query->whereIn('station_id', $stations);
                        }
                        $query->where('distributor_id', $info['id']);
                    })
                    ->where('status',Order::STATUS_END)
                    ->whereBetween('stop_at', [$startDate, $endDate])
                    ->groupBy(Db::raw('DATE_FORMAT(stop_at, "%Y-%m")'))
                    ->orderBy('month')
                    ->get();

            } else {
                return $this->error(code: 1001, msg: '无效的查询类型');
            }
            return $this->success([
                'type' => $type,
                'value' => $value,
                'list' => $list
            ]);
        } catch (\Exception $e) {
            Normal::logger($e->getMessage() . $e->getTraceAsString(), 'home');
            return $this->error(code: 1004, msg: $e->getMessage());
        }
    }



    /**
     * 获取盈利流水
     * @param RequestInterface $request
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    public function getBillLog(RequestInterface $request): ResponseInterface
    {
        try {
            $info = $this->distributors->getInfo($request);
            if (!$info) {
                return $this->error(code: '400', msg: '登录态失效 请重新登录');
            }
            $classId = $request->input('class_id', 0);
            $params = $request->inputs(['start', 'end', 'page', 'limit']);
            $stations = null;
            if($classId){
                $stations = Station::where('class_id', $classId)->pluck('id')->toArray();
            }
            $query = Db::table('bills as b')
                ->leftJoin('orders as o', 'b.target_id', '=', 'o.id')
                ->where('b.account_type', 1)
                ->where('b.account_id', $info['id'])
                ->where(function ($query) use ($params,$stations) {
                    if (isset($params['start']) && $params['start']) {
                        $query->where('b.created_at', '>=', $params['start']);
                    }
                    if (isset($params['end']) && $params['end']) {
                        $query->where('b.created_at', '<=', $params['end']);
                    }
                    if($stations){
                        $query->whereIn('o.station_id', $stations);
                    }
                });
            $data['total'] = $query->count();
            // 新增：计算总金额
            $data['total_fee'] = $query->clone()->sum('b.fee');
            $data['list'] = $query->orderBy('b.id', 'desc')
                ->offset(($params['page'] - 1) * $params['limit'])
                ->limit($params['limit'])
                ->get(['b.id', 'b.target_id', 'b.payment_type', 'b.type', 'b.created_at',
                    'b.fee', 'o.number', 'sn', 'channel_number']);
            return $this->success($data);
        } catch (\Exception $e) {
            Normal::logger($e->getMessage() . $e->getTraceAsString(), 'home');
            return $this->error(code: 1004, msg: $e->getMessage());
        }
    }

    /**
     * 导出订单
     * @param RequestInterface $request
     * @param HttpResponse $response
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     * @throws RedisException
     * @throws \PhpOffice\PhpSpreadsheet\Exception
     * @throws \PhpOffice\PhpSpreadsheet\Writer\Exception
     */
    public function orderExport(RequestInterface $request, HttpResponse $response): ResponseInterface
    {
        try {
            $info = $this->distributors->getInfo($request);
            if (!$info) {
                return $this->error(code: '400', msg: '登录态失效 请重新登录');
            }
            $page = $request->inputs(['sn', 'start', 'end']);
            $page['distributor_id'] = $info['id'];
            $data['list'] = Order::where(function ($query) use ($page) {
                if (array_key_exists('start', $page) && $page['start']) {
                    $query->where('created_at', '>=', $page['start']);
                }
                if (array_key_exists('end', $page) && $page['end']) {
                    $query->where('created_at', '<=', $page['end']);
                }
                $query->whereIn('status', [Order::STATUS_REFUNDED, Order::STATUS_END]);
                if (isset($page['sn']) && $page['sn']) {
                    $query->where('sn', $page['sn']);
                } else {
                    $query->where('distributor_id', $page['distributor_id']);
                }
            })
                ->orderBy('id', 'desc')
                ->with('user', 'station')
                ->get();
            // 创建新的 Spreadsheet 对象
            $spreadsheet = new Spreadsheet();
            $sheet = $spreadsheet->getActiveSheet();
            // 设置 Excel 文档的头部
            $sheet->setCellValue('A1', '订单编号');
            $sheet->setCellValue('B1', '充电用户');
            $sheet->setCellValue('C1', '开启时间');
            $sheet->setCellValue('D1', '关闭时间');
            $sheet->setCellValue('E1', '功率');
            $sheet->setCellValue('F1', '预付电费');
            $sheet->setCellValue('G1', '退款电费');
            $sheet->setCellValue('H1', '实收电费');
            $sheet->setCellValue('I1', '优惠');
            $sheet->setCellValue('J1', '地址');
            $sheet->setCellValue('K1', '桩号');
            $sheet->setCellValue('L1', '充电口');
            foreach (range('A', 'O') as $columnID) {
                $sheet->getColumnDimension($columnID)->setAutoSize(true);
            }

            // 设置单元格水平居中的样式数组配置
            $styleArray = [
                'alignment' => [
                    'horizontal' => Alignment::HORIZONTAL_CENTER,
                ],
            ];

            // 应用样式到第一行的A到O列
            $sheet->getStyle('A:O')->applyFromArray($styleArray);
            // 从第二行开始填充订单数据
            $row = 2;

            foreach ($data['list'] as $order) {
                $nickname = '未知';
                if($order->user){
                    $nickname = $order->user->nickname;
                }
                $sheet->setCellValue('A' . $row, $order->number . ' ');
                $sheet->setCellValue('B' . $row,$nickname );
                $sheet->setCellValue('C' . $row, $order->estimate_stop_at);
                $sheet->setCellValue('D' . $row, $order->stop_at);
                $sheet->setCellValue('E' . $row, $order->power);
                $sheet->setCellValue('F' . $row, $order->fee-$order->service_fee);
                $sheet->setCellValue('G' . $row, $order->return_fee);
                $sheet->setCellValue('H' . $row, number_format($order->fee - $order->return_fee-$order->service_fee, 2));
                if ($order->coupon_record_id) {
                    $sheet->setCellValue('I' . $row, '是');
                } else {
                    $sheet->setCellValue('I' . $row, '否');
                }

                $sheet->setCellValue('J' . $row, $order->station->name);
                $sheet->setCellValue('K' . $row, $order->sn);
                $sheet->setCellValue('L' . $row, $order->channel_number + 1);
                $row++;
            }
            // 将 Spreadsheet 对象写入 XLSX 文件
            $writer = new Xlsx($spreadsheet);
            // 创建临时文件
            $publicPath = BASE_PATH . '/public/upload/xls/';
            $fileName = date('YmdHis', time()) . '-orders.xlsx';
            $temp_file = $publicPath . $fileName;
            // 保存到临时文件
            $writer->save($temp_file);
            return $this->success(['url' => Common::MAIN_HOST . '/upload/xls/' . $fileName]);
        } catch (\Exception $e) {
            Normal::logger($e->getMessage() . $e->getTraceAsString(), 'home');
            return $this->error(code: 1004, msg: $e->getMessage());
        }
    }

    /**
     * @param RequestInterface $request
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    public function getWarningList(RequestInterface $request){
        $sn = $request->input('keyword');
        $page = $request->input('page',1);
        $limit = $request->input('limit',10);
        $status = $request->input('status',0);
        $info = $this->distributors->getInfo($request);
        try{
            $query = DevicePortErrLog::where(function ($query) use ($status,$sn,$info) {
                if($status != ''){
                    $query->where('status',$status);
                }
                if($sn){
                    $query->whereHas('device', function($q) use ($sn) {
                        $q->where('sn', $sn);
                    });
                }else{
                    $devices = Device::where('distributor_id', $info['id'])->pluck('id');
                    $query->whereIn('device_id',$devices);
                }
            });
            $data['total'] = $query->count();
            $data['list'] =  $query->with('device')
                ->offset(($page - 1) * $limit)
                ->limit($limit)
                ->get();
            return $this->success($data);
        }catch (\Exception $e){
            return $this->error(1001,$e->getMessage().$e->getTraceAsString());
        }
    }

    public function editWarning(RequestInterface $request){
        try {
            $id = $request->input('id');
            $model = DevicePortErrLog::find($id);
            $model->status = DevicePortErrLog::STATUS['handle_yes'];
            $model->save();
            return $this->success();
        } catch (\Exception $e) {
            return $this->error($e->getMessage());
        }
    }
    protected function downloadExcelFile(ResponseInterface $response, $fileName, $tempFile)
    {

        // 准备头部
        $headers = [
            'Content-Type' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
            'Content-Disposition' => 'attachment; filename="' . $fileName . '"',
            'Cache-Control' => 'max-age=0',
        ];

        foreach ($headers as $name => $value) {
            $response = $response->withHeader($name, $value);
        }
        $response->withStatus(200);
        // 发送下载响应
        return $response->download($tempFile, $fileName);
    }

}
